package com.etl.mongodb.dao;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.*;
import com.mongodb.client.MongoCollection;
import com.mongodb.util.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * mongodb　基础操作类
 * 
 * @author oyhk
 * 
 *         2013-1-22下午5:28:26
 */

public abstract class MongodbDao<T> {
	/**
	 * spring mongodb　集成操作类　
	 */
	@Autowired
	protected MongoTemplate mongoTemplate;


	/**
	 * 通过条件查询实体(集合)
	 * 
	 * @param query
	 */
	public List<T> find(Query query,String collectionName) {

		return (collectionName==null||collectionName.equals(""))?
				mongoTemplate.find(query,this.getEntityClass()):
				mongoTemplate.find(query, this.getEntityClass(),collectionName);
	}

	/**
	 * 通过一定的条件查询一个实体
	 * 
	 * @param query
	 * @return
	 */
	public T findOne(Query query,String collectionName) {
		return (collectionName==null||collectionName.equals(""))?
				mongoTemplate.findOne(query,this.getEntityClass()):
				mongoTemplate.findOne(query, this.getEntityClass(),collectionName);
	}

	/**
	 * 查询出所有数据
	 * 
	 * @return
	 */
	public List<T> findAll(String collectionName) {
		return(collectionName==null||collectionName.equals(""))?
				this.mongoTemplate.findAll(getEntityClass()):
				this.mongoTemplate.findAll(getEntityClass(),collectionName);
	}

	/**
	 * 查询并且修改记录
	 * 
	 * @param query
	 * @param update
	 * @return
	 */
	public T findAndModify(Query query, Update update,String collectionName) {
		return (collectionName==null||collectionName.equals(""))?
				this.mongoTemplate.findAndModify(query, update, this.getEntityClass()):
				this.mongoTemplate.findAndModify(query,update,this.getEntityClass(),collectionName);
	}

	/**
	 * 按条件查询,并且删除记录
	 * 
	 * @param query
	 * @return
	 */
	public T findAndRemove(Query query,String collectionName) {
		return (collectionName==null||collectionName.equals(""))?
				this.mongoTemplate.findAndRemove(query, this.getEntityClass()):
				this.mongoTemplate.findAndRemove(query,this.getEntityClass(),collectionName);
	}


	/**
	 * 通过ID获取记录,并且指定了集合名(表的意思)
	 * 
	 * @param id
	 * @param collectionName
	 *            集合名
	 * @return
	 */
	public T findById(String id, String collectionName) {
		return (collectionName==null||collectionName.equals(""))?
				mongoTemplate.findById(id, this.getEntityClass()):
				mongoTemplate.findById(id,this.getEntityClass(),collectionName);
	}

	/**
	 * 通过条件查询更新数据
	 * 
	 * @param query
	 * @param update
	 * @return
	 */
	public void updateFirst(Query query, Update update,String collectionName) {
		if ((collectionName == null || collectionName.equals(""))) {
			mongoTemplate.updateFirst(query, update, this.getEntityClass());
		} else {
			mongoTemplate.updateFirst(query, update, this.getEntityClass(), collectionName);
		}
	}

	/**
	 * 通过条件查询出多条记录(包含一条),全部修改(感觉很少用到),可以叫批量修改
	 * 
	 * @param query
	 * @param update
	 */
	public WriteResult updateMulti(Query query, Update update,String collectionName) {
		return (collectionName == null || collectionName.equals(""))?
				this.mongoTemplate.updateMulti(query, update, this.getEntityClass()):
				this.mongoTemplate.updateMulti(query, update, this.getEntityClass(),collectionName);
	}

	/**
	 * 通过条件查询出多条记录,全部修改,并且如果存在有新数据,也会同时插入到mongodb中..(简单说:更新或插入数据)
	 * 
	 * @param query
	 * @param update
	 */
	public WriteResult upsert(Query query, Update update,String collectionName) {
		return (collectionName == null || collectionName.equals(""))?
				this.mongoTemplate.upsert(query, update, this.getEntityClass()):
				this.mongoTemplate.upsert(query,update,this.getEntityClass(),collectionName);
	}



	/**
	 * 直接删除对象
	 * 
	 * @param bean
	 */
	public void remove(T bean,String collectionName) {
		if ((collectionName == null || collectionName.equals(""))) {
			this.mongoTemplate.remove(bean);
		} else {
			this.mongoTemplate.remove(bean, collectionName);
		}
	}

	/**
	 * 通过查询条件,删除对象
	 * 
	 * @param query
	 */
	public void remove(Query query,String collectionName) {
		if ((collectionName == null || collectionName.equals(""))) {
			this.mongoTemplate.remove(query);
		} else {
			this.mongoTemplate.remove(query, collectionName);
		}
	}

	/**
	 * 保存一个对象到mongodb
	 * 
	 * @param bean
	 * @return
	 */
	public T save(T bean,String collectionName) {
		if ((collectionName == null || collectionName.equals(""))) {
			this.mongoTemplate.save(bean);
		} else {
			this.mongoTemplate.save(bean, collectionName);
		}
		return bean;
	}


	/**
	 *
	 * 统计某一个 条件下的
	 * 数据集合数目
	 *
	 * @param query
	 * @param collectionName
	 * @return
	 */
	public long count(Query query,String collectionName){

		return (collectionName == null || collectionName.equals(""))?
				this.mongoTemplate.count(query,getEntityClass()):
				this.mongoTemplate.count(query,getEntityClass(),collectionName);
	}


	/**
	 *  批量插入数据
	 *
	 * @param objects
	 * @param collectionName
	 */
	public void batchInsert(List<JSONObject> objects, String collectionName){

		BasicDBList objects1 = parseFromJsonStrList(objects.toString());

		this.mongoTemplate.insert(objects1,collectionName);

	}



	/**
	 * 获取需要操作的实体类class
	 * 
	 * @return
	 */
	protected abstract Class<T> getEntityClass();

	/**
	 *
	 * jsonStr 转换成 MongoDb的DBObject
	 * 用于可操作
	 *
	 * @param jsonStr
	 * @return
	 */
	private DBObject parseFromJsonStr(String jsonStr){
		return (DBObject) JSON.parse(jsonStr);
	}

	private BasicDBList parseFromJsonStrList(String jsonStr){
		return (BasicDBList) JSON.parse(jsonStr);
	}

}
